package mi.payment.db;

import android.database.Cursor;
import android.text.TextUtils;

import org.greenrobot.greendao.identityscope.IdentityScopeType;
import org.greenrobot.greendao.query.DeleteQuery;
import org.greenrobot.greendao.query.QueryBuilder;
import org.greenrobot.greendao.query.WhereCondition;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import mi.payment.bean.db.CardInfo;
import mi.payment.bean.db.ICCardInfo;
import mi.payment.bean.db.MAGCardInfo;
import mi.payment.bean.db.TradeData;
import mi.payment.ui.print.helper.SumTotal;
import mi.payment.controller.BaseSupportController;
import mi.payment.controller.SupportController;
import mi.payment.db.dao.DBManager;
import mi.payment.db.dao.DaoMaster;
import mi.payment.db.dao.DaoSession;
import mi.payment.db.dao.PayDetail;
import mi.payment.db.dao.PayDetailDao;
import mi.payment.db.dao.PayDetailDao.Properties;
import mi.payment.db.dao.PaySettlement;
import mi.payment.utils.iso8583.DecodePackage;
import mi.payment.utils.iso8583.MsgField;
import sunmi.sunmiui.utils.LogUtil;

/**
 * 交易详情管理类
 */
public class PayDetailModel {

    protected DaoMaster daoMaster;
    protected DaoSession daoSession;
    protected PayDetailDao mPayDetailDao;

    private static CustomPayDetailModel mCustomPayDetailModel;

    public static final int PAGE_SIZE = 20; // 每页多少条数据

    public BaseSupportController mSupportController;

    protected PayDetailModel() {
        daoMaster = new DaoMaster(DBManager.getInstance().getWritableDatabase());
        daoSession = daoMaster.newSession(IdentityScopeType.None);
        mPayDetailDao = daoSession.getPayDetailDao();
        mSupportController = new SupportController(null);
    }

    public static CustomPayDetailModel getInstance() {
        if (mCustomPayDetailModel == null) {
            synchronized (PayDetailModel.class) {
                if (mCustomPayDetailModel == null) {
                    mCustomPayDetailModel = new CustomPayDetailModel();
                }
            }
        }
        return mCustomPayDetailModel;
    }

    /**
     * 读取指定页码的分页数据
     */
    public List<PayDetail> getPageData(int page) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.Amount.gt(0)).orderDesc(PayDetailDao.Properties.PID).limit(PAGE_SIZE).offset(page * PAGE_SIZE);
        List<PayDetail> list = qb.build().list();
        return list;
    }

    /**
     * 插入一条数据，插入时会强制置空PID,确保插入成功
     */
    public void insert(PayDetail payDetail) {
        payDetail.PID = null; // 强制置空PID
        mPayDetailDao.insert(payDetail);
        LogUtil.e("nsz", "insert db");
    }

    /**
     * 根据交易详情PID查询PayDetail
     */
    public PayDetail queryPayDetailById(Long id) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.PID.eq(id));
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 更新数据
     */
    public void update(PayDetail payDetail) {
        Long id = payDetail.getPID();
        if (id == null || id == 0) {
            insert(payDetail);
        } else {
            PayDetail pay = queryPayDetailById(id);
            if (pay != null) {
                mPayDetailDao.update(payDetail);
            }
        }
    }

    /**
     * 根据终端交易流水号更新的是否已打印标志
     */
    public void updateIsPrintedByVoucherNo(String VoucherNo, boolean isPrinted) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.VoucherNo.eq(VoucherNo)).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();
        if (payDetail != null) {
            payDetail.setIsPrinted(isPrinted);
            mPayDetailDao.update(payDetail);
        }
    }

    /**
     * 根据终端交易流水号更新的是否已撤销标志
     */
    public void updateIsCanceledByVoucherNo(String VoucherNo, boolean isCanceled) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.VoucherNo.eq(VoucherNo)).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();
        if (payDetail != null) {
            payDetail.setIsCanceled(isCanceled);
            mPayDetailDao.update(payDetail);
        }
    }

    /**
     * 根据交易流水号更新的交易应答码
     */
    public void updateAnswerCodeByVoucherNo(String VoucherNo, String answerCode) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.VoucherNo.eq(VoucherNo));
        PayDetail pay = qb.build().unique();
        // 更新状态
        if (pay != null) {
            pay.setTradeAnswerCode(answerCode);
            mPayDetailDao.update(pay);
        }
    }

    /**
     * 根据交易流水号更新是否已上送
     */
    public void updateIsUploadedByVoucherNo(String VoucherNo, boolean isUploaded) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.VoucherNo.eq(VoucherNo)).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail pay = qb.build().unique();
        // 更新是否已上送
        if (pay != null) {
            pay.setIsUploaded(isUploaded);
            mPayDetailDao.update(pay);
        }
    }

    /**
     * 根据支付二维码串数据更新是否已撤销
     */
    public void updateIsCanceledByPayQRCode(String payQRCode, boolean isCanceled) {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.PayQRCode.eq(payQRCode));
        PayDetail pay = qb.build().unique();
        // 更新是否已撤销
        if (pay != null) {
            pay.setIsCanceled(isCanceled);
            mPayDetailDao.update(pay);
        }

    }

    /**
     * 根据交易流水号更新是否已上送
     */
    public void updateIsUploadedByVoucherNo(List<PayDetail> list, boolean isUploaded) {

        for (PayDetail pay : list) {
            updateIsUploadedByVoucherNo(pay.getVoucherNo(), isUploaded);
        }

    }

    /**
     * 获取可撤销交易与已撤销交易的数据
     */
    public List<PayDetail> getRevocableAndRevokedList() {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(qb.or(PayDetailDao.Properties.TransactionType.eq(1), qb.and(PayDetailDao.Properties.IsCanceled.eq(true), PayDetailDao.Properties.TransactionType.eq(1))),
                PayDetailDao.Properties.TradeAnswerCode.eq("00"), PayDetailDao.Properties.TransPlatform.eq(0));
        qb.orderDesc(PayDetailDao.Properties.PID);
        List<PayDetail> list = qb.build().list();

        return list;
    }

    /**
     * 获取可撤销二维码交易与已撤销二维码交易的数据
     */
    public List<PayDetail> getRevocableAndRevokedListByQRCode() {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.notEq(0), PayDetailDao.Properties.TransactionType.eq(1), PayDetailDao.Properties.TradeAnswerCode.eq("00"), PayDetailDao.Properties.QRCodeTransState.eq(1));
        qb.orderDesc(PayDetailDao.Properties.PID);
        List<PayDetail> list = qb.build().list();

        return list;
    }


    /**
     * 根据微信或支付宝提供的交易号查询交易详情
     */
    public PayDetail getPayDetailByThirdTransNum(String thirdTransNum) {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.ThirdTransNum.eq(thirdTransNum)).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail pay = qb.build().unique();

        return pay;
    }

    //+ nsz ； 2017.9.11 ；添加根据订单号获取交易列表

    /**
     * 根据微信或支付宝提供的交易号查询交易列表
     */
    public List<PayDetail> getPayDetailByThirdTransNumList(String thirdTransNum) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.ThirdTransNum.eq(thirdTransNum)).orderDesc(PayDetailDao.Properties.PID);
        List<PayDetail> list = qb.build().list();
        return list;
    }
    //- nsz ； 2017.9.11 ；添加根据订单号获取交易列表

    /**
     * 获取可撤销 预授权完成 交易与已撤销 预授权完成 交易的数据
     */
    public List<PayDetail> getPreAuthorCompleteAndRevokedList() {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(qb.or(PayDetailDao.Properties.TransactionType.eq(6),
                qb.and(PayDetailDao.Properties.IsCanceled.eq(true), PayDetailDao.Properties.TransactionType.eq(6))),
                PayDetailDao.Properties.TradeAnswerCode.eq("00")
        );
        List<PayDetail> list = qb.build().list();

        return list;
    }

    /**
     * 获取可撤销的银行卡和二维码的数据
     */

    public List<PayDetail> getAllConsumptionData() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.whereOr(
                // 查询二维码消费记录
                qb.and(PayDetailDao.Properties.TradeAnswerCode.eq("00"),
                        PayDetailDao.Properties.TransPlatform.notEq(0),
                        PayDetailDao.Properties.TransactionType.eq(1),
                        PayDetailDao.Properties.QRCodeTransState.eq(1)),
                qb.and(PayDetailDao.Properties.TradeAnswerCode.eq("00"),
                        PayDetailDao.Properties.TransPlatform.eq(0),
                        qb.or(PayDetailDao.Properties.TransactionType.eq(1),
                                qb.and(PayDetailDao.Properties.IsCanceled.eq(true),
                                        PayDetailDao.Properties.TransactionType.eq(1)))));
        qb.orderDesc(PayDetailDao.Properties.PID);
        List<PayDetail> list = qb.build().list();
        return list;
    }

    /**
     * 根据凭证号获取可撤销的银行卡和二维码的数据
     */
    public List<PayDetail> getAllConsumptionDataWithVoucherNo(String voucherNo) {
        if (voucherNo.length() < 6) {
            String vou = "";
            for (int i = 0; i < 6 - voucherNo.length(); i++) {
                vou += ("0");
            }
            voucherNo = vou + voucherNo;
        }
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.whereOr(
                // 查询二维码消费记录
                qb.and(PayDetailDao.Properties.TradeAnswerCode.eq("00"),
                        PayDetailDao.Properties.TransPlatform.notEq(0),
                        PayDetailDao.Properties.TransactionType.eq(1),
                        PayDetailDao.Properties.VoucherNo.eq(voucherNo),
                        PayDetailDao.Properties.QRCodeTransState.eq(1)),
                qb.and(PayDetailDao.Properties.TradeAnswerCode.eq("00"),
                        PayDetailDao.Properties.TransPlatform.eq(0),
                        PayDetailDao.Properties.VoucherNo.eq(voucherNo),
                        qb.or(PayDetailDao.Properties.TransactionType.eq(1),
                                qb.and(PayDetailDao.Properties.IsCanceled.eq(true),
                                        PayDetailDao.Properties.TransactionType.eq(1)))));
        qb.orderDesc(PayDetailDao.Properties.PID);
        List<PayDetail> list = qb.build().list();

        return list;
    }

    /**
     * 获取交易明细单列表数据
     */
    public List<PayDetail> getTransactionList() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.whereOr(
                // 查询二维码消费记录
                qb.and(PayDetailDao.Properties.IsNeedReversal.eq(false),
                        PayDetailDao.Properties.IsReversal.eq(false),
                        PayDetailDao.Properties.TradeAnswerCode.eq("00"),
                        PayDetailDao.Properties.TransPlatform.notIn(0, 3),
                        //+xr, 2017-09-11, 消费、撤销、退货交易成功后都要置QRCodeTransState=1；失败QRCodeTransState=-1，支付中QRCodeTransState=2,查询条件要随之更改
                        PayDetailDao.Properties.QRCodeTransState.in(1)),
                //-xr, 2017-09-11, 消费、撤销、退货交易成功后都要置QRCodeTransState=1；失败QRCodeTransState=-1，支付中QRCodeTransState=2,查询条件要随之更改

                // 查询银行卡消费记录
                qb.and(
                        PayDetailDao.Properties.IsNeedReversal.eq(false),
                        PayDetailDao.Properties.IsReversal.eq(false),
                        PayDetailDao.Properties.TradeAnswerCode.eq("00"),
                        PayDetailDao.Properties.TransPlatform.eq(0),
                        qb.or(
                                PayDetailDao.Properties.TransactionType.eq(6),
                                PayDetailDao.Properties.TransactionType.eq(7),
                                PayDetailDao.Properties.TransactionType.eq(1),
                                PayDetailDao.Properties.TransactionType.eq(2),
                                PayDetailDao.Properties.TransactionType.eq(3)
                        ))
        );
        List<PayDetail> list = qb.build().list();
        return list;
    }

    /**
     * 获取二维码交易明细单列表数据
     */
    public List<PayDetail> getQrTransactionList() {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.IsNeedReversal.eq(false),
                PayDetailDao.Properties.IsReversal.eq(false),
                PayDetailDao.Properties.TradeAnswerCode.eq("00"),
                PayDetailDao.Properties.TransPlatform.notEq(0),
                //+xr, 2017-09-11, 消费、撤销、退货交易成功后都要置QRCodeTransState=1；失败QRCodeTransState=-1，支付中QRCodeTransState=2,查询条件要随之更改
                PayDetailDao.Properties.QRCodeTransState.in(1));
        //-xr, 2017-09-11, 消费、撤销、退货交易成功后都要置QRCodeTransState=1；失败QRCodeTransState=-1，支付中QRCodeTransState=2,查询条件要随之更改
        List<PayDetail> list = qb.build().list();

        return list;
    }

    /**
     * 获取银行卡交易明细单列表数据
     */
    public List<PayDetail> getCardTransactionList() {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.IsCanceled.eq(false),
                PayDetailDao.Properties.IsNeedReversal.eq(false),
                PayDetailDao.Properties.IsReversal.eq(false),
                PayDetailDao.Properties.TradeAnswerCode.eq("00"),
                PayDetailDao.Properties.TransPlatform.eq(0),
                qb.or(PayDetailDao.Properties.TransType.eq("22"),
                        PayDetailDao.Properties.TransType.eq("25"),
                        PayDetailDao.Properties.TransType.eq("20")));
        List<PayDetail> list = qb.build().list();

        return list;
    }


    /**
     * 获取最后一条待冲正记录
     */
    public PayDetail getLastWaitForCorrection() {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.IsNeedReversal.eq(true),
                PayDetailDao.Properties.IsReversal.eq(false)).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail pay = qb.build().unique();

        return pay;
    }

    /**
     * 获取最后一条二次授权脚本处理完成的记录
     */
    public PayDetail getLastAurhorizationProcess() {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.ConfirmBag.isNotNull(), PayDetailDao.Properties.ConfirmBag.notEq(""), PayDetailDao.Properties.ScriptUploadStatus.eq("1"), Properties.ScriptResult.isNotNull(), PayDetailDao.Properties.ScriptResult.notEq("")).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail pay = qb.build().unique();

        return pay;
    }

    /**
     * 获取所有待冲正记录
     */
    public List<PayDetail> getWaitForCorrection() {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.IsNeedReversal.eq(true));
        List<PayDetail> list = qb.list();

        return list;
    }

    /**
     * 获取最后一条数据
     */
    public PayDetail getLastData() {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail pay = qb.build().unique();

        return pay;
    }

    /**
     * 获取最后一条打单的数据
     */
    public PayDetail getLastPrintData() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        WhereCondition condition = Properties.IsPrinted.eq(true);
        qb.where(condition)
                .orderDesc(PayDetailDao.Properties.PID)
                .limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 获取最后一条交易结果39域返回00的成功交易
     */
    public PayDetail getLastSuccessTrade() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        WhereCondition eqCode = Properties.TradeAnswerCode.eq("00");
        WhereCondition eqPlatform = Properties.TransPlatform.eq(0);
        WhereCondition bank = qb.and(eqPlatform, eqCode);
        WhereCondition eqState = Properties.QRCodeTransState.eq(1);
        WhereCondition notEqPlatform = Properties.TransPlatform.notEq(0);
        WhereCondition qrCode = qb.and(notEqPlatform, eqCode, eqState);
        qb.whereOr(bank, qrCode)
                .orderDesc(PayDetailDao.Properties.PID)
                .limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 获取最后一条非二维码交易结果39域返回00的成功交易
     */
    public PayDetail getLastNotQRCodeSuccessTrade() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TradeAnswerCode.eq("00"),
                PayDetailDao.Properties.TransPlatform.eq(0)
        ).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 获取最后一条二维码的消费交易记录
     */
    public PayDetail getLastQRCodeConsumptionTrade() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        Object[] queryCondition = getSupportedPlatform();
        qb.where(PayDetailDao.Properties.TransPlatform.notIn(0, 3),
                PayDetailDao.Properties.TransactionType.in(queryCondition))
                .orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 获取最后一条支付宝二维码的消费交易记录
     */
    public PayDetail getLastQRCodeByAliPay() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.eq(1)
        ).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 获取最后一条微信二维码的消费交易记录
     */
    public PayDetail getLastQRCodeByWeChat() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.eq(2)
        ).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 查询口碑最后一笔交易
     */
    public PayDetail getLastQRCodeByKouBei() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.eq(3)
        ).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    // 获取最后一笔银行卡消费记录
    public PayDetail getLastBankCardConsumptionTrade() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(Properties.TransType.in("1", "2", "3", "22", "23", "25")
        ).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 查询银联二维码最后一笔交易
     */
    public PayDetail getLastQRCodeByUnion() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.eq(4)
        ).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 获取最后一条成功的二维码交易记录
     */
    public PayDetail getLastQRCodeTrade() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.gt(0),
                PayDetailDao.Properties.TransactionType.in(1, 2, 3),
                PayDetailDao.Properties.TradeAnswerCode.eq("00")
        ).orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();

        return payDetail;
    }

    /**
     * 获取所有未打印订单列表
     */
    public List<PayDetail> getNotPrintedList() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.IsPrinted.eq(false));
        List<PayDetail> list = qb.build().list();
        return list;
    }

    /**
     * 获取所有交易记录的列表
     */
    public List<PayDetail> getPrintedList() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.IsPrinted.eq(true));
        List<PayDetail> list = qb.build().list();
        return list;
    }

    /**
     * 根据ID删除交易详情
     */
    public void deletePayDetailById(String voucherNo) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        DeleteQuery<PayDetail> dq = qb.where(PayDetailDao.Properties.VoucherNo.eq(voucherNo)
        ).buildDelete();
        dq.executeDeleteWithoutDetachingEntities();
    }

    /**
     * 清空历史库
     */
    public void deleteAll() {
        mPayDetailDao.deleteAll();
    }

    /**
     * 读取保存总条数
     */
    public int getPayDetailCount() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        return qb.build().list().size();
    }

    /**
     * 根据批次号获取交易列表
     */
    public List<PayDetail> getPayDetailByBathNo(String bathNo) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        WhereCondition condition = Properties.BathNo.eq(bathNo);
        qb.where(condition);
        List<PayDetail> list = qb.build().list();
        return list;
    }

    /**
     * 根据参考号获取交易明细
     */
    public PayDetail getPayDetailByTransRefNo(String transRefNo) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        WhereCondition condition = Properties.ReferNo.eq(transRefNo);
        qb.where(condition)
                .orderDesc(PayDetailDao.Properties.PID)
                .limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 根据交易号获取交易明细
     */
    public PayDetail getPayDetailByTransNum(long transNum) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        WhereCondition condition = Properties.TransNum.eq(transNum);
        qb.where(condition)
                .orderDesc(PayDetailDao.Properties.PID)
                .limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 根据流水ID获取明细
     */
    public PayDetail getPayDetailById(String VoucherNo) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        WhereCondition condition = Properties.VoucherNo.eq(VoucherNo);
        qb.where(condition)
                .orderDesc(PayDetailDao.Properties.PID)
                .limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 根据自定义订单号获取明细
     */
    public PayDetail getPayDetailByCustomOrderNo(String customOrderNo) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        WhereCondition condition = Properties.CustomOrderNo.eq(customOrderNo);
        qb.where(condition)
                .orderDesc(PayDetailDao.Properties.PID)
                .limit(1);
        PayDetail payDetail = qb.build().unique();
        return payDetail;
    }

    /**
     * 根据流水ID获取成功的交易明细
     */
    public PayDetail getSuccessPayDetailByVoucherNo(String voucherNo) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        WhereCondition condition = Properties.VoucherNo.eq(voucherNo);
        qb.where(condition)
                .orderDesc(PayDetailDao.Properties.PID)
                .limit(1);
        PayDetail payDetail = qb.build().unique();
        // 扫码消费、撤销、退货交易，必须成功才有返回
        if (payDetail != null && TextUtils.equals("00", payDetail.tradeAnswerCode) && payDetail.transPlatform == 0)
            return payDetail;
        if (payDetail != null && TextUtils.equals("00", payDetail.tradeAnswerCode) && payDetail.transPlatform > 0 && payDetail.QRCodeTransState == 1)
            return payDetail;
        return null;
    }

    /**
     * 获取银行卡结算总计(内卡)
     */
    public List<SumTotal> getSumTotalNotForeignCard() {
        String sql = "SELECT " + PayDetailDao.Properties.TransType.columnName + " ,COUNT(*), SUM(" + PayDetailDao.Properties.Amount.columnName + ") FROM " + PayDetailDao.TABLENAME
                + " WHERE " +
                PayDetailDao.Properties.IsForeignCard.columnName + " = 0 AND " +
                // PayDetailDao.Properties.IsCanceled.columnName + " = 0 AND " +
                PayDetailDao.Properties.IsNeedReversal.columnName + " = 0 AND " +
                PayDetailDao.Properties.IsReversal.columnName + " = 0 AND " +
                PayDetailDao.Properties.TransPlatform.columnName + " = 0 AND " +
                PayDetailDao.Properties.TradeAnswerCode.columnName + " = '00' AND " +
                "(" + PayDetailDao.Properties.TransType.columnName + " = 20 " +
                " OR " + PayDetailDao.Properties.TransType.columnName + " = 21 " +
                " OR " + PayDetailDao.Properties.TransType.columnName + " = 22 " +
                " OR " + PayDetailDao.Properties.TransType.columnName + " = 23 " +
                " OR " + PayDetailDao.Properties.TransType.columnName + " = 25 " + " )" +
                " GROUP BY " + PayDetailDao.Properties.TransType.columnName;
        Cursor cursor = null;
        try {
            List<SumTotal> sumTotals = new ArrayList<>();
            cursor = daoSession.getDatabase().rawQuery(sql, null);
            while (cursor.moveToNext()) {
                String type = cursor.getString(0);
                String times = cursor.getString(1);
                String sum = cursor.getString(2);

                SumTotal mSumTotal = new SumTotal();
                mSumTotal.setTransType(type);
                mSumTotal.setTransTimes(times);
                mSumTotal.setSumMoney(sum);
                sumTotals.add(mSumTotal);
            }
            return sumTotals;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return null;
    }

    /**
     * 获取银行卡结算总计（外卡）
     */
    public List<SumTotal> getSumTotalForeignCard() {
        String sql = "SELECT " + PayDetailDao.Properties.TransType.columnName + " ,COUNT(*), SUM(" + PayDetailDao.Properties.Amount.columnName + ") FROM " + PayDetailDao.TABLENAME
                + " WHERE " +
                PayDetailDao.Properties.IsForeignCard.columnName + " = 1 AND " +
                PayDetailDao.Properties.IsCanceled.columnName + " = 0 AND " +
                PayDetailDao.Properties.IsNeedReversal.columnName + " = 0 AND " +
                PayDetailDao.Properties.IsReversal.columnName + " = 0 AND " +
                PayDetailDao.Properties.TransPlatform.columnName + " = 0 AND " +
                PayDetailDao.Properties.TradeAnswerCode.columnName + " = '00' AND " +
                "(" + PayDetailDao.Properties.TransType.columnName + " = 20 " +
                " OR " + PayDetailDao.Properties.TransType.columnName + " = 21 " +
                " OR " + PayDetailDao.Properties.TransType.columnName + " = 22 " +
                " OR " + PayDetailDao.Properties.TransType.columnName + " = 23 " +
                " OR " + PayDetailDao.Properties.TransType.columnName + " = 25 " + " )" +
                " GROUP BY " + PayDetailDao.Properties.TransType.columnName;
        Cursor cursor = null;
        try {
            List<SumTotal> sumTotals = new ArrayList<>();
            cursor = daoSession.getDatabase().rawQuery(sql, null);
            while (cursor.moveToNext()) {
                String type = cursor.getString(0);
                String times = cursor.getString(1);
                String sum = cursor.getString(2);

                SumTotal mSumTotal = new SumTotal();
                mSumTotal.setTransType(type);
                mSumTotal.setTransTimes(times);
                mSumTotal.setSumMoney(sum);
                sumTotals.add(mSumTotal);
            }
            return sumTotals;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return null;
    }

    public List<SumTotal> getSumTotalQRCode() {
        List<SumTotal> list = getSumTotalQRCodeOri();
        Map<String, SumTotal> map = new HashMap<>();
        for (SumTotal item : list) {
            String key = item.platform + item.transType;
            SumTotal total = map.get(key);
            if (total == null) {
                total = item;
            }
            total = calculateSumTotal(total, item, total.transType);
            map.put(key, total);
        }
        Collection<SumTotal> values = map.values();
        return new ArrayList<>(values);
    }

    private SumTotal calculateSumTotal(SumTotal total, SumTotal item, String transType) {
        int countRet = Integer.parseInt(total.transTimes);
        int count = Integer.parseInt(item.transTimes);
        countRet += count;
        total.setTransTimes(countRet + "");
        long amountRet = Long.parseLong(total.sumMoney);
        long amount = Long.parseLong(item.sumMoney);
        amountRet += amount;
        total.setSumMoney(amountRet + "");
        total.setTransType(transType);
        return total;
    }

    /**
     * 获取二维码交易结算总计（二维码）
     */
    public List<SumTotal> getSumTotalQRCodeOri() {
        String sql = "SELECT " +
                PayDetailDao.Properties.TransPlatform.columnName + " , " +
                PayDetailDao.Properties.TransactionType.columnName + " ,COUNT(*), SUM(" +
                PayDetailDao.Properties.Amount.columnName + ") FROM " + PayDetailDao.TABLENAME + " WHERE " +
                PayDetailDao.Properties.IsNeedReversal.columnName + " = 0 AND " +
                PayDetailDao.Properties.IsReversal.columnName + " = 0 AND " +
                PayDetailDao.Properties.TradeAnswerCode.columnName + " = '00' AND " +
                PayDetailDao.Properties.TransPlatform.columnName + " >0 AND " +
                PayDetailDao.Properties.QRCodeTransState.columnName + " =1 " + " GROUP BY " +
                PayDetailDao.Properties.TransPlatform.columnName + "," +
                PayDetailDao.Properties.TransactionType.columnName;
        Cursor cursor = null;
        try {
            List<SumTotal> sumTotals = new ArrayList<>();
            cursor = daoSession.getDatabase().rawQuery(sql, null);
            boolean next = cursor.moveToNext();
            while (next) {
                String platform = cursor.getString(0);
                String type = cursor.getString(1);
                String times = cursor.getString(2);
                String sum = cursor.getString(3);

                SumTotal sumTotal = new SumTotal();
                sumTotal.setPlatform(platform);
                sumTotal.setTransType(type);
                sumTotal.setTransTimes(times);
                sumTotal.setSumMoney(sum);
                sumTotals.add(sumTotal);
                next = cursor.moveToNext();
            }
            return sumTotals;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return null;
    }

    /**
     * 根据交易参考号获取TradeData
     */
    public TradeData getTradeDataByReferNo(String referNo) {

        PayDetail mPayDetail = getPayDetailByTransRefNo(referNo);
        if (mPayDetail != null) {
            TradeData mTradeData = new TradeData();
            if (mPayDetail.sendBag != null) {
                mTradeData.setSend8583(DecodePackage.unAssembly(mPayDetail.sendBag));
            }
            if (mPayDetail.receiverBag != null) {
                mTradeData.setReceive8583(DecodePackage.unAssembly(mPayDetail.receiverBag));
            }
            mTradeData.setSendBag(mPayDetail.sendBag);
            mTradeData.setReceiveBag(mPayDetail.receiverBag);

            PaySettlement mPaySettlement = SettlementModel.getInstance().getPaySettlementByBatchNo(mPayDetail.BathNo);
            mTradeData.setPaySettlement(mPaySettlement);
            mTradeData.setPayDetail(mPayDetail);

            CardInfo cardInfo = getCardInfoByPayDetail(mTradeData);
            mTradeData.setCardInfo(cardInfo);
            return mTradeData;
        }
        return null;
    }

    /**
     * 根据流水号获取TradeData
     */
    public TradeData getTradeDataByVoucherNo(String voucherNo) {
        PayDetail payDetail = getPayDetailById(voucherNo);
        if (payDetail != null) {
            TradeData tradeData = new TradeData();
            // 给交易的原始信息赋值
            if (!TextUtils.isEmpty(payDetail.getAuthNo())) {
                payDetail.setOriginalAuthNo(payDetail.getAuthNo());
            }
            if (!TextUtils.isEmpty(payDetail.getBathNo())) {
                payDetail.setOriginalBathNo(payDetail.getBathNo());
            }
            if (!TextUtils.isEmpty(payDetail.getVoucherNo())) {
                payDetail.setOriginalPOSNum(payDetail.getVoucherNo());
            }
            if (!TextUtils.isEmpty(payDetail.getReferNo())) {
                payDetail.setOriginalReferNo(payDetail.getReferNo());
            }
            if (!TextUtils.isEmpty(payDetail.getTradeDate())) {
                payDetail.setOriginalTransDate(payDetail.getTradeDate());
            }
            // 赋值交易的时候不打印log
            LogUtil.setLevel(LogUtil.NOTHING);
            if (payDetail.sendBag != null) {
                tradeData.setSend8583(DecodePackage.unAssembly(payDetail.sendBag));
            }
            if (payDetail.receiverBag != null) {
                tradeData.setReceive8583(DecodePackage.unAssembly(payDetail.receiverBag));
            }
            LogUtil.setLevel(LogUtil.VERBOSE);
            tradeData.setSendBag(payDetail.sendBag);
            tradeData.setReceiveBag(payDetail.receiverBag);
            PaySettlement mPaySettlement = SettlementModel.getInstance().getPaySettlementByBatchNo(payDetail.BathNo);
            tradeData.setPaySettlement(mPaySettlement);
            tradeData.setPayDetail(payDetail);
            CardInfo cardInfo = getCardInfoByPayDetail(tradeData);
            tradeData.setCardInfo(cardInfo);
            return tradeData;
        }
        return null;
    }

    /**
     * 根据PayDetail获取CardInfo
     */
    public CardInfo getCardInfoByPayDetail(TradeData tradeData) {
        PayDetail mPayDetail = tradeData.getPayDetail();
        CardInfo cardInfo = new CardInfo();
        // IC卡相关信息
        ICCardInfo icCardInfo = new ICCardInfo();
        // 应用ID
        icCardInfo.setAID(mPayDetail.AID);
        // 应用标签
        icCardInfo.setAppLabel(mPayDetail.appLabel);
        // 应用首选名称
        icCardInfo.setAppName(mPayDetail.appName);
        // TVR
        icCardInfo.setTVR(mPayDetail.TVR);
        // TSI
        icCardInfo.setTSI(mPayDetail.TSI);
        // ATC
        icCardInfo.setATC(mPayDetail.ATC);
        // TC
        icCardInfo.setTC(mPayDetail.TC);
        // 发卡行认证数据
        icCardInfo.setIssuerVerityData(mPayDetail.issuerVerifyData);
        // 脚本处理结果
        icCardInfo.setScriptResult(mPayDetail.scriptResult);
        // 密文信息数据
        icCardInfo.setCID(mPayDetail.CID);
        // 脚本1长度
        icCardInfo.setScript1Length(mPayDetail.script1Length);
        // 脚本2长度
        icCardInfo.setScript2Length(mPayDetail.script2Length);
        // 脚本1内容(用于二磁授权处理)71
        icCardInfo.setScript1Content(mPayDetail.script1Content);
        // 脚本2内容(用于二磁授权处理)72
        icCardInfo.setScript2Content(mPayDetail.script2Content);
        // ic卡55域数据
        icCardInfo.setICC55(mPayDetail.ic55);
        // A R P C状态
        icCardInfo.setARPCStatus(mPayDetail.ARPCStatus);
        // 发卡行应用数据
        icCardInfo.setBankAppDate(mPayDetail.issuingBankAppData);
        cardInfo.setICCardInfo(icCardInfo);

        // 磁条卡相关信息
        MAGCardInfo magCardInfo = new MAGCardInfo();
        // 卡有效期
        magCardInfo.setExpireDate(mPayDetail.EXPDate);
        // 是否为IC卡
        magCardInfo.setIccCard(mPayDetail.isICCardTrans);
        // 国家代码
        magCardInfo.setCountryCode(mPayDetail.currencyCode);
        MsgField fieldF035 = tradeData.getSend8583().get("F035");
        if (fieldF035 != null) {
            magCardInfo.setTrack2Cipher(fieldF035.getDataStr());
        }
        MsgField fieldF036 = tradeData.getSend8583().get("F036");
        if (fieldF036 != null) {
            magCardInfo.setTrack3Cipher(fieldF036.getDataStr());
        }
        cardInfo.setMAGCardInfo(magCardInfo);
        return cardInfo;
    }


    /**
     * 根据交易平台ID删除相应的记录
     */
    public void deletePayDetailByQrCodeTransPlatform(int qrCodeTransPlatform) {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        DeleteQuery<PayDetail> dq = qb.where(PayDetailDao.Properties.TransPlatform.eq(qrCodeTransPlatform)).buildDelete();
        dq.executeDeleteWithoutDetachingEntities();

    }


    /**
     * 根据支付方式和交易类型获得交易列表
     */
    public List<PayDetail> getPayDetailByQrCodeTransPlatformAndQrCodeTransType(int qrCodeTransPlatform, int qrCodeTransType) {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.eq(qrCodeTransPlatform), PayDetailDao.Properties.TransactionType.eq(qrCodeTransType),
                PayDetailDao.Properties.TradeAnswerCode.eq("00"), Properties.QRCodeTransState.eq("1")).orderAsc(Properties.TerminalDate);
        List<PayDetail> list = qb.list();

        return list;
    }

    /**
     * 根据交易类型查询银行卡消费成功的交易记录列表
     */
    public List<PayDetail> getSuccessPayDetailByTransactionType(int transactionType) {

        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.eq(0),
                PayDetailDao.Properties.TransactionType.eq(transactionType),
                PayDetailDao.Properties.TradeAnswerCode.eq("00")).orderAsc(Properties.TerminalDate);
        List<PayDetail> list = qb.list();

        return list;
    }

    /**
     * 获取扫码末笔查询交易类型列表 消费 撤销 退货
     */
    public Object[] getSupportedPlatform() {
        Object[] queryCondition = new Integer[]{1, 2, 3};
        return queryCondition;
    }

    /**
     * 查询所有收款记录
     */
    public List<PayDetail> queryAllCollectMoneyRecords() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.notEq(3),
                PayDetailDao.Properties.TransactionType.in(1, 4, 6)
        ).orderDesc(Properties.TerminalDate);
        return qb.list();
    }

    /**
     * 查询所有收款记录
     */
    public List<PayDetail> queryAllCollectMoneyRecords(boolean isFilerOrder) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.notEq(3),
                PayDetailDao.Properties.TransactionType.in(1, 4, 6)
        ).orderDesc(Properties.TerminalDate);
        return qb.list();
    }

    /**
     * 查询所有退款记录
     */
    public List<PayDetail> queryAllRefundRecords() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.notEq(3),
                PayDetailDao.Properties.TransactionType.in(2, 3, 5, 7)
        ).orderDesc(Properties.TerminalDate);
        return qb.list();
    }

    /**
     * 查询所有退款记录
     */
    public List<PayDetail> queryAllRefundRecords(boolean isFilerOrder) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.TransPlatform.notEq(3),
                PayDetailDao.Properties.TransactionType.in(2, 3, 5, 7)
        ).orderDesc(Properties.TerminalDate);
        return qb.list();
    }

    /**
     * 按凭证号或订单号搜索订单
     */
    public List<PayDetail> queryTransRecord(String voucherNo) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(qb.or(PayDetailDao.Properties.VoucherNo.like("%" + voucherNo + "%"),
                PayDetailDao.Properties.ThirdTransNum.like("%" + voucherNo + "%")))
                .orderDesc(Properties.TerminalDate);
        return qb.list();
    }

    /*
     * 获取所有交易列表
     */
    public List<PayDetail> getAllTrades() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        WhereCondition condition = Properties.TransPlatform.notEq(3);
        qb.where(condition)
                .orderDesc(PayDetailDao.Properties.PID);
        List<PayDetail> list = qb.list();
        return list;
    }


    /**
     * 获取待上送电子签名列表
     * 支持电子签名包括 1:消费 2：消费撤销；3：退货  4.预授权 5.预授权撤销 6.预授权完成 7.预授权完成撤销
     */
    public List<PayDetail> getUnUploadESignList() {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(
                PayDetailDao.Properties.TransPlatform.eq(0),
                PayDetailDao.Properties.TransactionType.in(1, 2, 3, 4, 5, 6, 7),
                Properties.ESignHexData.isNotNull(),
                PayDetailDao.Properties.ESignIsUploaded.eq(false),
                PayDetailDao.Properties.TradeAnswerCode.eq("00")
        );
        List<PayDetail> list = qb.build().list();
        return list;
    }

    /**
     * 根据payDetail的ID更新电子签名上送
     */
    public void updateESignIsUploaded(PayDetail payDetail) {
        PayDetail pay = queryPayDetailById(payDetail.getPID());
        if (pay != null) {
            pay.setESignIsUploaded(true);
            mPayDetailDao.update(pay);
        }
    }

    /**
     * 根据银行卡号，授权号 获取交易凭证号
     */
    public PayDetail getVoucherNoByCardNOAndAuthNo(String cardNo, String authNo) {
        QueryBuilder<PayDetail> qb = mPayDetailDao.queryBuilder();
        qb.where(PayDetailDao.Properties.CardNo.eq(cardNo),
                PayDetailDao.Properties.AuthNo.eq(authNo))
                .orderDesc(PayDetailDao.Properties.PID).limit(1);
        PayDetail payDetail = qb.build().unique();

        return payDetail;
    }

}
